package main

import (
	"context"
	"encoding/json"
	"errors"
	"flag"
	"fmt"
	"log"
	"os"

	"github.com/redis/go-redis/v9"
)

const (
	RedisURL  = "43.198.246.1"
	RedisPort = 18379
)

var (
	redisClient *redis.Client
	ctx         = context.Background()
)

// 初始化Redis客户端
func init() {
	redisClient = redis.NewClient(&redis.Options{
		Addr:     fmt.Sprintf("%s:%d", RedisURL, RedisPort),
		Password: "", // 无密码
		DB:       0,  // 默认DB
	})
}

// Order 表示订单的结构体
type Order struct {
	Type       string                 `json:"type"`
	Account    string                 `json:"account"`
	QID        string                 `json:"qid"`
	SecurityID string                 `json:"securityID"`
	Side       string                 `json:"side"`
	OrderType  string                 `json:"orderType,omitempty"`
	OrderQty   int                    `json:"orderQty,omitempty"`
	Price      float64                `json:"price,omitempty"`
	OpenClose  string                 `json:"openClose,omitempty"`
	ClOrdID    string                 `json:"ClOrdID,omitempty"`
	Sym        string                 `json:"sym"`
	Algo       map[string]interface{} `json:"algo,omitempty"`
}

// SendOrder 发送新订单
func SendOrder(account, qid, securityID, orderType string, orderQty int, price float64, side, openClose string, algo map[string]interface{}) error {
	// 验证订单类型
	if orderType != "1" && orderType != "2" { // 1:市价 2:限价
		return errors.New("incorrect value for orderType")
	}

	// 验证买卖方向
	if side != "1" && side != "2" && side != "5" { // 1:买 2:卖 5:卖空
		return errors.New("incorrect value for side")
	}

	// 验证开平标志
	if openClose != "O" && openClose != "C" { // O:开 C:平
		return errors.New("incorrect value for openClose")
	}

	// 创建订单对象
	order := Order{
		Type:       "new",
		Account:    account,
		QID:        qid,
		SecurityID: securityID,
		Side:       side,
		OrderType:  orderType,
		OrderQty:   orderQty,
		Price:      price,
		OpenClose:  openClose,
		Sym:        securityID,
	}

	// 添加算法交易参数（如果有）
	if algo != nil {
		order.Algo = algo
	}

	// 序列化订单为JSON
	jsonData, err := json.Marshal(order)
	if err != nil {
		return fmt.Errorf("error marshaling order: %w", err)
	}

	// 发布到Redis
	err = redisClient.Publish(ctx, "newOrder", jsonData).Err()
	if err != nil {
		return fmt.Errorf("error publishing to Redis: %w", err)
	}

	fmt.Printf("订单已发送: %s\n", string(jsonData))
	return nil
}

// CancelOrder 取消订单
func CancelOrder(account, securityID, side, clOrdID, qid string) error {
	// 验证买卖方向
	if side != "1" && side != "2" {
		return errors.New("incorrect value for side")
	}

	// 创建取消订单对象
	order := Order{
		Type:       "cancel",
		Account:    account,
		SecurityID: securityID,
		Side:       side,
		ClOrdID:    clOrdID,
		QID:        qid,
		Sym:        securityID,
	}

	// 序列化订单为JSON
	jsonData, err := json.Marshal(order)
	if err != nil {
		return fmt.Errorf("error marshaling cancel order: %w", err)
	}

	// 发布到Redis
	err = redisClient.Publish(ctx, "newOrder", jsonData).Err()
	if err != nil {
		return fmt.Errorf("error publishing to Redis: %w", err)
	}

	fmt.Printf("取消订单已发送: %s\n", string(jsonData))
	return nil
}

// AmendOrder 修改订单
func AmendOrder(account, clOrdID, orderType, securityID, side string, price float64, orderQty int, openClose, qid string) error {
	// 验证订单类型
	if orderType != "1" && orderType != "2" {
		return errors.New("incorrect value for orderType")
	}

	// 验证买卖方向
	if side != "1" && side != "2" && side != "5" {
		return errors.New("incorrect value for side")
	}

	// 验证开平标志
	if openClose != "O" && openClose != "C" {
		return errors.New("incorrect value for openClose")
	}

	// 创建修改订单对象
	order := Order{
		Type:       "replace",
		Account:    account,
		QID:        qid,
		ClOrdID:    clOrdID,
		SecurityID: securityID,
		Side:       side,
		OrderType:  orderType,
		OrderQty:   orderQty,
		Price:      price,
		OpenClose:  openClose,
		Sym:        securityID,
	}

	// 序列化订单为JSON
	jsonData, err := json.Marshal(order)
	if err != nil {
		return fmt.Errorf("error marshaling amend order: %w", err)
	}

	// 发布到Redis
	err = redisClient.Publish(ctx, "newOrder", jsonData).Err()
	if err != nil {
		return fmt.Errorf("error publishing to Redis: %w", err)
	}

	fmt.Printf("修改订单已发送: %s\n", string(jsonData))
	return nil
}

func main() {
	// 创建子命令
	sendCmd := flag.NewFlagSet("send", flag.ExitOnError)
	cancelCmd := flag.NewFlagSet("cancel", flag.ExitOnError)
	amendCmd := flag.NewFlagSet("amend", flag.ExitOnError)

	// send 命令的参数
	sendAccount := sendCmd.String("account", "", "账户ID")
	sendQID := sendCmd.String("qid", "", "订单QID")
	sendSecurityID := sendCmd.String("securityID", "", "证券ID")
	sendOrderType := sendCmd.String("orderType", "", "订单类型 (1:市价 2:限价)")
	sendOrderQty := sendCmd.Int("orderQty", 0, "订单数量")
	sendPrice := sendCmd.Float64("price", 0.0, "订单价格")
	sendSide := sendCmd.String("side", "", "买卖方向 (1:买 2:卖 5:卖空)")
	sendOpenClose := sendCmd.String("openClose", "", "开平标志 (O:开 C:平)")

	// cancel 命令的参数
	cancelAccount := cancelCmd.String("account", "", "账户ID")
	cancelSecurityID := cancelCmd.String("securityID", "", "证券ID")
	cancelSide := cancelCmd.String("side", "", "买卖方向 (1:买 2:卖)")
	cancelClOrdID := cancelCmd.String("ClOrdID", "", "原订单ID")
	cancelQID := cancelCmd.String("qid", "", "订单QID")

	// amend 命令的参数
	amendAccount := amendCmd.String("account", "", "账户ID")
	amendClOrdID := amendCmd.String("ClOrdID", "", "原订单ID")
	amendOrderType := amendCmd.String("orderType", "", "订单类型 (1:市价 2:限价)")
	amendSecurityID := amendCmd.String("securityID", "", "证券ID")
	amendSide := amendCmd.String("side", "", "买卖方向 (1:买 2:卖 5:卖空)")
	amendPrice := amendCmd.Float64("price", 0.0, "订单价格")
	amendOrderQty := amendCmd.Int("orderQty", 0, "订单数量")
	amendOpenClose := amendCmd.String("openClose", "", "开平标志 (O:开 C:平)")
	amendQID := amendCmd.String("qid", "", "订单QID")

	// 检查命令行参数
	if len(os.Args) < 2 {
		fmt.Println("使用方法: fix_order <命令> [参数]")
		fmt.Println("可用命令: send, cancel, amend")
		os.Exit(1)
	}

	// 根据子命令解析参数
	switch os.Args[1] {
	case "send":
		sendCmd.Parse(os.Args[2:])
		if *sendAccount == "" || *sendQID == "" || *sendSecurityID == "" || *sendOrderType == "" ||
			*sendOrderQty == 0 || *sendSide == "" || *sendOpenClose == "" {
			sendCmd.PrintDefaults()
			os.Exit(1)
		}
		err := SendOrder(*sendAccount, *sendQID, *sendSecurityID, *sendOrderType, *sendOrderQty, *sendPrice, *sendSide, *sendOpenClose, nil)
		if err != nil {
			log.Fatalf("发送订单失败: %v", err)
		}

	case "cancel":
		cancelCmd.Parse(os.Args[2:])
		if *cancelAccount == "" || *cancelSecurityID == "" || *cancelSide == "" || *cancelClOrdID == "" || *cancelQID == "" {
			cancelCmd.PrintDefaults()
			os.Exit(1)
		}
		err := CancelOrder(*cancelAccount, *cancelSecurityID, *cancelSide, *cancelClOrdID, *cancelQID)
		if err != nil {
			log.Fatalf("取消订单失败: %v", err)
		}

	case "amend":
		amendCmd.Parse(os.Args[2:])
		if *amendAccount == "" || *amendClOrdID == "" || *amendOrderType == "" || *amendSecurityID == "" ||
			*amendSide == "" || *amendOrderQty == 0 || *amendOpenClose == "" || *amendQID == "" {
			amendCmd.PrintDefaults()
			os.Exit(1)
		}
		err := AmendOrder(*amendAccount, *amendClOrdID, *amendOrderType, *amendSecurityID, *amendSide, *amendPrice, *amendOrderQty, *amendOpenClose, *amendQID)
		if err != nil {
			log.Fatalf("修改订单失败: %v", err)
		}

	default:
		fmt.Printf("未知命令: %s\n", os.Args[1])
		fmt.Println("可用命令: send, cancel, amend")
		os.Exit(1)
	}
}
